﻿using System;
using System.Collections.Generic;

namespace GMC_4
{
    enum OpCode
    {
        KA,
        AO,
        CH,
        CY,
        AM,
        MA,
        Mp,
        Mm,
        TIA,
        AIA,
        TIY,
        AIY,
        CIA,
        CIY,
        CAL,
        JUMP
    }

    enum Subroutine
    {
        RSTO,
        SETR,
        RSTR,
        ____,
        CMPL,
        CHNG,
        SIFT,
        ENDS,
        ERRS,
        SHTS,
        LONS,
        SUND,
        TIMR,
        DSPR,
        DEMm,
        DEMp
    }

    static class Ops
    {
        public static string[] OpText { get; private set; }
        public static string[] SubroutineText { get; private set; }
        public static int[] ParamCounts { get; private set; }
        public static Dictionary<string, byte> OpTable { get; private set; }
        public static Dictionary<string, byte> SubroutineTable { get; private set; }

        static Ops()
        {
            OpText = (string[])Enum.GetNames(typeof(OpCode)).Clone();
            SubroutineText = (string[])Enum.GetNames(typeof(Subroutine)).Clone();
            OpText[(int)OpCode.Mp] = "M+";
            OpText[(int)OpCode.Mm] = "M-";
            SubroutineText[(int)Subroutine.DEMp] = "DEM+";
            SubroutineText[(int)Subroutine.DEMm] = "DEM-";

            ParamCounts = new int[OpText.Length];
            ParamCounts[(int)OpCode.KA] = 0;
            ParamCounts[(int)OpCode.AO] = 0;
            ParamCounts[(int)OpCode.CH] = 0;
            ParamCounts[(int)OpCode.CY] = 0;
            ParamCounts[(int)OpCode.AM] = 0;
            ParamCounts[(int)OpCode.MA] = 0;
            ParamCounts[(int)OpCode.Mp] = 0;
            ParamCounts[(int)OpCode.Mm] = 0;
            ParamCounts[(int)OpCode.TIA] = 1;
            ParamCounts[(int)OpCode.AIA] = 1;
            ParamCounts[(int)OpCode.TIY] = 1;
            ParamCounts[(int)OpCode.AIY] = 1;
            ParamCounts[(int)OpCode.CIA] = 1;
            ParamCounts[(int)OpCode.CIY] = 1;
            ParamCounts[(int)OpCode.CAL] = 1;
            ParamCounts[(int)OpCode.JUMP] = 2;

            OpTable = new Dictionary<string, byte>();
            foreach (OpCode opCode in Enum.GetValues(typeof(OpCode)))
            {
                string name = OpText[(int)opCode].ToLowerInvariant();
                byte value = (byte)opCode;
                OpTable[name] = value;
            }

            SubroutineTable = new Dictionary<string, byte>();
            foreach (Subroutine subroutine in Enum.GetValues(typeof(Subroutine)))
            {
                string name = SubroutineText[(int)subroutine].ToLowerInvariant();
                byte value = (byte)subroutine;
                SubroutineTable[name] = value;
            }
        }
    }
}
